package com.lethe.config;

import com.lethe.entity.User;
import com.lethe.service.UserService;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;

/**
 * 自定义Reaml
 */
public class UserReaml extends AuthorizingRealm {

    @Autowired
    private UserService userService;


    /**
     * ==授权==
     *
     * @param principalCollection
     * @return
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();

        //拿到当前登录的用户信息
        Subject subject = SecurityUtils.getSubject();
        User currentUser = (User) subject.getPrincipal();

        //设置当前用户权限(从数据库中拿到当前用户的权限信息)
        info.addStringPermission(currentUser.getPower());

        return info;
    }

    /**
     * ==认证==
     * 用户一旦登陆就会到此方法进行认证
     * 这里全程密码是不可见的看不见明文密码
     * 验证密码已经交给了shiro处理
     * 登陆服务只需要查询用户名就可以了
     *
     * @param authenticationToken
     * @return 是否登陆成功
     * @throws AuthenticationException
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        //拿到用户的登录信息
        UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;

        //通过数据库查询登录信息
        User user = userService.login(token.getUsername());

        //用户名认证：当return null时就会在登录Controller中抛出异常
        if (user == null) {
            return null;
        }

        //将登陆信息放入session中
        SecurityUtils.getSubject().getSession().setAttribute("currentUser", user);

        //密码可加密：MD5加密，MD5盐值加密等
        //密码认证：不需要用户做，shiro做(防止密码泄露)
        //参数列表：SimpleAuthenticationInfo(当前用户信息, 密码, "");
        //注意:如果当前用户信息为空的话，在授权中就拿不到当前用户的信息
        return new SimpleAuthenticationInfo(user, user.getPassword(), "");
    }
}
